#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// using namespace std;

class UdpServer
{
    public:
    UdpServer(std::string ip, int port)
		:_sockfd(-1)
		,_port(port)
		,_ip(ip)
	{};
    bool InitServer()
    {
        //一、创建套接字
        _sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(_sockfd<0)//创建套接字失败
        {
            std::cerr<<"server socket error"<<std::endl;
            return false;
        }

        //创建套接字成功
        std::cout<<"server socket create success, sockfd: "<<_sockfd<<std::endl;
        
        //填充网络通信相关信息
        struct sockaddr_in local;
        memset(&local,'\0',sizeof(local));//清0
        local.sin_family=AF_INET;//协议族设置为 网络通信 
        local.sin_port=htons(_port);//16位主机序列转化为网络序列
        local.sin_addr.s_addr=inet_addr(_ip.c_str());//字符串ip地址转化为32位u整数ip地址
        
        
        //二、绑定
        if(bind(_sockfd,(struct sockaddr*)&local,sizeof(sockaddr))<0)//绑定失败
        {
            std::cerr<<"server bind error"<<std::endl;
            return false;
        }
        
        std::cout<<"server bind success"<<std::endl;
        
        return true;        
    }


    void Start()
    {
        #define SIZE 128
        char buffer[SIZE];
        while(true)
        {
            sleep(1);
             //三、接收数据，并获取对端网络相关信息
            struct sockaddr_in peer;
            socklen_t len =sizeof(peer);
            
            ssize_t size=recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
            
            
            if(size>0)
            {
                
                buffer[size]='\0';
                int port=ntohs(peer.sin_port);//16位unsgined short 转 int
                std::string ip=inet_ntoa(peer.sin_addr);//struct sock_in 转 char*(再构造string对象)

                std::cout<<ip<<":"<<"# "<<buffer<<std::endl;//将收到的信息打印出来


            }
            else
            {
                std::cerr<<"server recvfrom error"<<std::endl;
            }       
        }
    }
    ~UdpServer()
    {
        if(_sockfd>=0)//析构时，如果套接字没有被关闭，则将其关闭
        close(_sockfd);
    }

    private:
    int _sockfd;//文件描述符
    int _port;//端口号
    std::string _ip;//ip地址
};